<?php
/**
 * @package trading
 */
class TradeHistory extends DataObject implements PermissionProvider {
    private static $singular_name = "Trade History";
    private static $plural_name = "Trade Histories";

    private static $db = array(
        'Type' => "Enum(array('Buy', 'Sell'))",
        'Reference' => 'Varchar',
        'Unit' => 'Int',
        'Price' => 'TradeCurrency',
        'ReservedPrice' => 'TradeCurrency',
        'Fee' => 'TradeCurrency',
        'IsCompany' => 'Boolean'
    );

    private static $has_one = array(
        'Member' => 'Member',
        'TradeSetting' => 'TradeSetting'
    );

    private static $default_sort = "Created DESC";

    private static $searchable_fields = array(
    	'Created' => array(
			'field' => 'DateField',
			'filter' => 'DateMatchFilter'
		),
    	'Member.Username',
    	'Member.FirstName',
    	'Member.Surname',
        'Type',
        'Reference',
        'Unit' => array(
            'filter' => 'GreaterThanOrEqualFilter'
        ),
        'Price' => array(
            'filter' => 'GreaterThanOrEqualFilter'
        ),
        'IsCompany'
    );

    private static $summary_fields = array(
    	'Member.Username',
    	'Member.Name',
    	'Created.Nice',
        'Type',
        'Reference',
        'Unit',
        'Price',
        'Fee',
        'Amount',
        'IsCompany.Nice'
    );
	
	private static $casting = array(
		'Amount' => 'TradeCurrency',
		'ReservedAmount' => 'TradeCurrency'
	);

    public function fieldLabels($includerelations = true) {
        $labels = parent::fieldLabels($includerelations);

		$labels['Created'] = _t('TradeHistory.DATE', 'Date');
		$labels['Created.Nice'] = _t('TradeHistory.DATE', 'Date');
        $labels['Type'] = _t('TradeHistory.TYPE', 'Type');
		$labels['Reference'] = _t('TradeHistory.REFERENCE', 'Reference');
        $labels['Unit'] = _t('TradeHistory.UNIT', 'Unit');
        $labels['Price'] = _t('TradeHistory.PRICE', 'Price');
		$labels['ReservedPrice'] = _t('TradeHistory.RESERVED_PRICE', 'Reserved Price');
        $labels['Fee'] = _t('TradeHistory.FEE', 'Fee');
		$labels['Amount'] = _t('TradeHistory.AMOUNT', 'Amount');
		$labels['ReservedAmount'] = _t('TradeHistory.RESERVED_AMOUNT', 'Reserved Amount');
		$labels['IsCompany'] = _t('TradeHistory.IS_COMPANY', 'Is Company?');
		$labels['IsCompany.Nice'] = _t('TradeHistory.IS_COMPANY', 'Is Company?');
		$labels['TradeSetting'] = _t('TradeHistory.TRADE_SETTING', 'Trade Setting');
		$labels['TradeSettingID'] = _t('TradeHistory.TRADE_SETTING', 'Trade Setting');
		$labels['Member.Username'] = _t('TradeHistory.USERNAME', 'Username');
		$labels['Member.FirstName'] = _t('TradeHistory.FIRST_NAME', 'First Name');
		$labels['Member.Surname'] = _t('TradeHistory.SURNAME', 'Surname');
		$labels['Member.Name'] = _t('TradeHistory.NAME', 'Name');
		$labels['Member'] = _t('TradeHistory.NAME', 'Name');

        return $labels;
    }

    function validate() {
        $validationResult = parent::validate();

        if(!$this->MemberID) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.INVALID_MEMBER_ID', 'Invalid Member ID'), 'INVALID_MEMBER_ID');
            $validationResult->combineAnd($subvalid);
        }
		
		if(!$this->Type) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.INVALID_TRADE_TYPE', 'Invalid trade type'), 'INVALID_TRADE_TYPE');
            $validationResult->combineAnd($subvalid);
        }

        if($this->Unit <= 0) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.INVALID_TRADE_UNIT', 'Invalid trade unit'), 'INVALID_TRADE_UNIT');
            $validationResult->combineAnd($subvalid);
        }

        if($this->Price <= 0) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.INVALID_TRADE_PRICE', 'Invalid trade price'), 'INVALID_TRADE_PRICE');
            $validationResult->combineAnd($subvalid);
        }
		
		if($this->Fee < 0) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.INVALID_TRADE_FEE', 'Invalid trade fee'), 'INVALID_TRADE_FEE');
            $validationResult->combineAnd($subvalid);
        }
		
		if(!$this->TradeSettingID) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.INVALID_TRADE_SETTING_ID', 'Invalid trade setting id'), 'INVALID_TRADE_SETTING_ID');
            $validationResult->combineAnd($subvalid);
        }
		else if(!$this->TradeSetting()->IsActive || !$this->TradeSetting()->IsStarted || $this->TradeSetting()->IsClosed){
			$subvalid = new ValidationResult();
            $subvalid->error(_t('TradeHistory.TRADE_MARKET_CLOSE', 'Sorry, currently trade market is closed'), 'TRADE_MARKET_CLOSE');
            $validationResult->combineAnd($subvalid);
		}

        return $validationResult;
    }

	function onBeforeWrite(){
		parent::onBeforeWrite();
		if(!$this->exists()){
			$this->ReservedPrice = $this->TradeSetting()->Price;
		}
	}

    function onAfterWrite() {
        parent::onAfterWrite();
		if($this->Type == 'Buy') {
			if(!$trade_account = TradeAccount::get()->filter('TradeSettingID', $this->TradeSettingID)->find('MemberID', $this->MemberID)){
				$trade_account = TradeAccount::create();
				$trade_account->MemberID = $this->MemberID;
				$trade_account->TradeSettingID = $this->TradeSettingID;
			}
			
	        $trade_account->TradeUnit += $this->Unit;
			$trade_account->TradeDeposit += $this->ReservedAmount;
			
			if($this->IsCompany){
				$this->TradeSetting()->SellUnit += $this->Unit;
				$this->TradeSetting()->SellVolume += $this->Amount;
				$price = $this->TradeSetting()->TradePrice($this->Price);
				$price->CompanyUnit += $this->Unit;
				$price->write();
				$this->TradeSetting()->write();
			}
			else{
				$price = $this->TradeSetting()->TradePrice($this->Price);
				$price->MemberUnit += $this->Unit;
				$price->write();
			}
			
			$trade_account->write();
        }
        
        if($this->Type == 'Sell') {
        	if(!$trade_account = TradeAccount::get()->filter('TradeSettingID', $this->TradeSettingID)->find('MemberID', $this->MemberID)){
				$trade_account = TradeAccount::create();
				$trade_account->MemberID = $this->MemberID;
				$trade_account->TradeSettingID = $this->TradeSettingID;
			}
			
        	$trade_account->TradeUnit -= $this->Unit;
			
			if($this->IsCompany){
				$trade_account->TradeDeposit -= $this->ReservedAmount;
		        $this->TradeSetting()->BuyUnit += $this->Unit;
				$this->TradeSetting()->BuyVolume += $this->Amount;
				$price = $this->TradeSetting()->TradePrice($this->Price);
				$price->CompanyUnit -= $this->Unit;
				$price->write();
				$this->TradeSetting()->write();
			}
			
			$trade_account->write();
        }
    }

	function getName(){
		return $this->TradeSetting()->Title;
	}
	
	function getAmount(){
		return $this->Price * $this->Unit;
	}
	
	function getReservedAmount(){
		return $this->ReservedPrice * $this->Unit;
	}
	
	function canView($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check('VIEW_TradeHistory');
    }

    function canEdit($member = false) {
        return false;
    }

    function canDelete($member = false) {
        return false;
    }

    function canCreate($member = false) {
        return false;
    }

    public function providePermissions() {
        return array(
            'VIEW_TradeHistory' => array(
                'name' => _t('TradeHistory.PERMISSION_VIEW', 'Allow view access right'),
                'category' => _t('TradeHistory.PERMISSIONS_CATEGORY', 'Trade History')
            )
        );
    }
}
?>